﻿using Newtonsoft.Json;
using Sustainalytics.ClientDW.DataAccessLayer;
using Sustainalytics.ClientDW.Entities;
using Sustainalytics.Companies;
using Sustainalytics.DataLayer.ConnectionStrings;
using Sustainalytics.DataLayer.Shared;
using Sustainalytics.Entities.ConnectionStrings;
using Sustainalytics.FileManager;
using Sustainalytics.LongRunningTaskManager;
using Sustainalytics.LongRunningTaskManager.Interface;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Globalization;
using System.IO;
using System.Linq;
using MongoDB.Bson;
using MongoDB.Driver;
using Sustainalytics.AwsS3.Client;
using Sustainalytics.Entities;
using Sustainalytics.MongoDB.Extensions;
using Sustainalytics.Utils;
using Sustainalytics.Utils.Configuration;

namespace Sustainalytics.GCCS.Tasks
{
    /// <summary>
    /// LRTM for creating GC PDF exports.
    /// </summary>
    public class GccsPdfExportTask : ILongRunningTask
    {
        // export manager
        private readonly IGCExportManager _gcExportManager;
        private readonly IGCOverallCompanySummaryManager _overallCompanySummaryManager;
        private readonly IRepositoryCollection<GCCurrentQuarter> _currentQuarterRepo;
        private readonly string _clientDwConnStr;

        /// <summary>
        /// Task type.
        /// </summary>
        public LongRunningTaskTypeEnum Type => LongRunningTaskTypeEnum.GccsReportPdf;

        /// <summary>
        /// Ctor.
        /// </summary>
        public GccsPdfExportTask()
        {
            var clientPlatformCnx = ConfigurationManager.ConnectionStrings["ClientPlatform"].ConnectionString;
            var connectionStringsManager =
                ConnectionStringsManager.GetInstance(ConnectionStringsRepository.GetInstance(clientPlatformCnx));

            _clientDwConnStr = connectionStringsManager.GetConnectionString(ConnectionStringType.ClientDW);


            var imageFileManager = new DiskFileManager(@"Images\GcPdfExport");

            var clientDwRepo = ClientDWGlobalCompactRepository.GetInstance(_clientDwConnStr);
            _currentQuarterRepo = new RepositoryCollection<GCCurrentQuarter>(_clientDwConnStr);

            _overallCompanySummaryManager = new GCOverallCompanySummaryManager(clientDwRepo);
            var principleSummaryExtendedManager = new GCPrincipleSummaryExtendedManager(clientDwRepo);
            var principleEventIndicatorExtendedManager = new GCPrincipleEventIndicatorExtendedManager(clientDwRepo);
            var sourceManager = new GCSourceManager(clientDwRepo);


            // create GC Export Manager
            this._gcExportManager = new GCExportManager(
                _currentQuarterRepo,
                imageFileManager: imageFileManager,
                overallCompanySummaryManager: _overallCompanySummaryManager,
                principleSummaryExtendedManager: principleSummaryExtendedManager,
                principleEventIndicatorExtendedManager: principleEventIndicatorExtendedManager,
                sourceManager: sourceManager);
 
        }

        public object Start(LongRunningTaskContext context)
        {
            // get task params
            var taskParams = GetTaskParams(context);

            // get company name
            var companyName = GetCompanyCompanyName(taskParams.CompanyId);

            var currentQuarter = _currentQuarterRepo.ReadAll().FirstOrDefault() ??
                                 new GCCurrentQuarter {Date = DateTime.Now.Date};

            var fileName = taskParams.OverallAssessment.GetFullReportName(companyName, currentQuarter.Date);

            context.Title = fileName;
            context.TaskStatus.Progress = 10;


            // get universes for current user
            var universeIds = GCCSUtility.GetUniverses(taskParams.OverallAssessment, context.Ticket.Identity.Claims);


            LongRunningTaskS3FileResult result = null;

            var overallCompanySummary = _overallCompanySummaryManager.GetByCompany(universeIds, taskParams.CompanyId, null);

            if (overallCompanySummary == null) return result;

            result = TryGetReportFromS3(taskParams, universeIds, companyName);

            context.TaskStatus.Progress = 100;

            result.FileName = fileName;


            return result;
        }


        private LongRunningTaskS3FileResult TryGetReportFromS3(GccsPdfExportTaskParams taskParams, List<int> universeIds, string companyName)
        {
            var s3BucketName = SettingsHelper.Read("s3bucket", "dev-globalaccess-europe");

            var s3Client = new S3Client(
                new S3ClientSettings
                {
                    AccessKey = SettingsHelper.Read("accesKeyId", "AKIAJEMY5FHDRQOHGPVA"),
                    SecretAccessKey = SettingsHelper.Read("awsSecretKey", "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"),
                    ServiceEndPoint = SettingsHelper.Read("s3ServiceEndPoint", "https://s3-eu-west-1.amazonaws.com/")
                });

            var remotePath = $"{ReportType.GlobalCompactComplianceReport}";
            var pdfFileName = taskParams.OverallAssessment.GetFullReportName(companyName, taskParams.CompanyId);
            var filePath = $"{remotePath}/{pdfFileName}";
 
            LongRunningTaskS3FileResult result;

            if (!s3Client.FileExists(s3BucketName, filePath))
            {
                var pdfExport = _gcExportManager.GetPdfExport(universeIds, taskParams.CompanyId, taskParams.OverallAssessment, null, false);

                s3Client.UploadFile(s3BucketName, filePath, pdfExport);

 
                result = new LongRunningTaskS3FileResult
                {
                    MimeType = "application/pdf",
                    Bucket = s3BucketName,
                    FileName = string.Empty,
                    Key = filePath
                };
            }
            else
            {
                result = new LongRunningTaskS3FileResult
                {
                    MimeType = "application/pdf",
                    Bucket = s3BucketName,
                    FileName = string.Empty,
                    Key = filePath
                };
            }

            return result;
        }


        private GccsPdfExportTaskParams GetTaskParams(LongRunningTaskContext context)
        {
            if (string.IsNullOrEmpty(context.ParamJson))
            {
                throw new GccsPdfExportTaskInvalidParamsException(context.ParamJson);
            }

            // get parameters
            var taskParams = JsonConvert.DeserializeObject<GccsPdfExportTaskParams>(context.ParamJson);

            if (taskParams == null)
            {
                throw new GccsPdfExportTaskInvalidParamsException(context.ParamJson);
            }

            return taskParams;
        }

        public string GetCompanyCompanyName(Guid id)
        {
            try
            {
                var collection = MongoFactory.GetCollectionFromDatabase<CorporateData>(_clientDwConnStr);

                var filter = Builders<CorporateData>.Filter.Eq(cd => cd.Id, id);

                var corporateData = collection.Find(filter)
                    .Project(cd => new CorporateData
                    {
                        Id = cd.Id,
                        CompanyName = cd.CompanyName
                    })
                    .SingleOrDefault();


                if (corporateData == null)
                {
                    throw new CompanyNotFoundException();
                }

                return corporateData.CompanyName;
            }
            catch (Exception ex)
            {

                CompaniesSerilog.Log.GetCompanyByIdError(id.ToString(), ex);

                throw;
            }
        }

    }
}
